/* This an the abstract base class all types of CPU Schedulers will derive from */
#ifndef SCHEDULER
#define SCHEDULER

#include "Process.h"
#include <vector>

using namespace std; 

class Abstract_CPUScheduler
{
    public:

		Abstract_CPUScheduler();
		~Abstract_CPUScheduler();
 
		void init(vector<Process*> newList);
		void sortProcesses();		
        void createCSVFile();
        void determineStats();
		void runScheduler();
		double getMeanWaitingTime();
		double getMeanTurnAroundTime();
		double getMeanResponseTime();
		Process getNextJob();

    protected:

        vector<Process> processList;
        /* Statistic Variables */
        double meanWaitingTime;
        double meanTurnAroundTime;
        double meanResponseTime;

        /* Called in sequence from public function determineStats() */
        void determineMeanWaitingTime();
        void determineMeanTurnAroundTime();
        void determineMeanResponseTime();

};

#endif

#ifndef PROCESS
#define PROCESS


class Process
{
	private:
		int arrivalTime;
		int StartTime;
		int EndTime;
		int CPU_Burst;
		int ProcessID;
		bool finished;
		bool processed;

	public:
		Process();
		Process(int Burst, int arrival, int id) { CPU_Burst = Burst; arrivalTime = arrival; ProcessID = id; StartTime = 0; EndTime = 0; finished = false; processed = false; };
		int getStartTime() { return StartTime; };
		int getEndTime() { return EndTime; };
		int getCPU_Burst() { return CPU_Burst; };
		int getProcessID() { return ProcessID; };
		int getArrivalTIme() { return arrivalTime; };
		bool isFinished() { return finished; };
		bool wasProcessed() { return processed; };
		
		void setEndTime(int end) { EndTime = end; };
		void setStartTime(int start) { StartTime = start; };
		void setCPU_Burst(int burst) { CPU_Burst = burst; };
		void setFinished() { finished = true; };
		void setProcessed() { processed = true; };

};

#endif



#include "Scheduler.h"
#include <vector>
#include <iostream>

using namespace std;

Abstract_CPUScheduler::Abstract_CPUScheduler()
{
}

Abstract_CPUScheduler::~Abstract_CPUScheduler()
{
	processList.~vector();
}

/*
	This init function accepts a vector of pointers to Processesm and creates a copy
	of the processes into the private member function 'processList'
*/
void Abstract_CPUScheduler::init(vector<Process*> newList)
{	
	vector<Process*>::iterator create;

	for(create = newList.begin(); create != newList.end(); create++)
		processList.push_back(**create);

}


void Abstract_CPUScheduler::determineMeanWaitingTime()
{
    vector<Process>::iterator index;
    int sum = 0;
    
	for(index = processList.begin(); index != processList.end(); index++)
	{
		sum += ((*index).getEndTime() - (*index).getArrivalTIme() - (*index).getCPU_Burst());
	}

    meanWaitingTime = static_cast<double>(sum) / static_cast<double>(processList.size());
}

void Abstract_CPUScheduler::determineMeanTurnAroundTime()
{
    vector<Process>::iterator index;
    int sum = 0;
    
	for(index = processList.begin(); index != processList.end(); index++)
		sum += (*index).getEndTime() - (*index).getStartTime();

	meanTurnAroundTime = static_cast<double>(sum) / static_cast<double>(processList.size());
}

void Abstract_CPUScheduler::determineStats()
{
	determineMeanWaitingTime();
	determineMeanTurnAroundTime();
	determineMeanResponseTime();
}

double Abstract_CPUScheduler::getMeanWaitingTime()
{
	return meanWaitingTime;
}

double Abstract_CPUScheduler::getMeanTurnAroundTime()
{
	return meanTurnAroundTime;
}

double Abstract_CPUScheduler::getMeanResponseTime()
{
	return meanResponseTime;
}

void Abstract_CPUScheduler::determineMeanResponseTime() 
{
	vector<Process>::iterator index;
    int sum = 0;
    
	for(index = processList.begin(); index != processList.end(); index++)
		sum +=  (*index).getStartTime() - (*index).getArrivalTIme();

	meanTurnAroundTime = static_cast<double>(sum) / static_cast<double>(processList.size());

}

#ifndef FCFS_SCHEDULER
#define FCFS_SCHEDULER

#include "Scheduler.h"

class FCFS_Scheduler : public Abstract_CPUScheduler
{
    public:
		FCFS_Scheduler();
		void sortProcesses();
		Process getNextProcess();
		void runScheduler();
		void printList();

	private:

		bool compareStartTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo);
        

};


#endif


#include "FCFS_Scheduler.h"
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

FCFS_Scheduler::FCFS_Scheduler()
{
}


void FCFS_Scheduler::runScheduler()
{
	int endTimeOfPreviousProcess = 0;
	vector<Process>::reverse_iterator process;

	//sort processes in descending order
	sortProcesses();

	//iterate through the processList in reverse order
	for(process = processList.rbegin(); process != processList.rend(); process++)
	{
		if(process == processList.rbegin())
		{
			//first process came in at time zero
			if((*process).getArrivalTIme() == 0)
			{
				(*process).setEndTime((*process).getCPU_Burst());
				(*process).setStartTime((*process).getArrivalTIme());
			}
			else //first process came in after time 0
			{
				(*process).setStartTime((*process).getArrivalTIme());
				(*process).setEndTime((*process).getCPU_Burst() + (*process).getArrivalTIme());
				
			}
		}
		else
		{
			//process came in after the previos process finished
			if((*process).getStartTime() > endTimeOfPreviousProcess)
			{
				(*process).setStartTime((*process).getArrivalTIme());
				(*process).setEndTime((*process).getStartTime() + (*process).getCPU_Burst());
			}
			else
			{ //process came in before at the same time the previous process finished
				(*process).setEndTime(endTimeOfPreviousProcess + (*process).getCPU_Burst());
				(*process).setStartTime(endTimeOfPreviousProcess);
			}
		}

		endTimeOfPreviousProcess = (*process).getEndTime();
		//cout << "Start Time: " << (*process).getStartTime() << "        End Time: " << (*process).getEndTime() << "       Burst: " << (*process).getCPU_Burst() << endl;
		}
}

Process FCFS_Scheduler::getNextProcess()
{
	Process nextJob = processList.back();
	processList.pop_back();
	return nextJob;
}

bool FCFS_Scheduler::compareStartTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo)
{
	//cout << "values: " << (*positionOne)->getStartTime() << "    " << (*positionTwo)->getStartTime();
	return (*positionOne).getStartTime() < (*positionTwo).getStartTime();
}

void FCFS_Scheduler::sortProcesses()
{
	vector<Process>::iterator end, positionOne, positionTwo;
	bool swapped = true;

	end = processList.end();

	do
	{
		swapped = false;
		positionTwo = ++processList.begin();
		for(positionOne = processList.begin(); positionTwo != end; positionOne++, positionTwo++)
		{
			if(compareStartTime(positionOne, positionTwo))
			{
				swap(*positionOne, *positionTwo);
				swapped = true;
			}
		}
	}while(swapped);
}

void FCFS_Scheduler::printList()
{
	vector<Process>::iterator begin, end, index;

	begin = processList.begin();
	end = processList.end();

	for(index = begin; index < end; index++)
		cout << (*index).getStartTime() << "   ";
}


#ifndef SJF_SCHEDULER
#define SJF_SCHEDULER

#include "Scheduler.h"

class SJF_Scheduler : public Abstract_CPUScheduler
{

	public:
		SJF_Scheduler();
		~SJF_Scheduler();
		void sortProcesses();
		void runScheduler();
		void printList();

	protected:
		bool compareArrivalTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo);
		bool compareCPU_Burst(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo);
		void getQueuedProcesses(vector<Process> &available_queue, vector<Process>::iterator &processListItr, int prevProcEndTime);
		void assignValuesToProcessList(Process temp);
		void findProcessID(vector<Process>::iterator &location, int processID);
		void sortQueueByTime(vector<Process> &queue);
};

#endif


#include "SJF_Scheduler.h"
#include <iostream>
#include <vector>

using namespace std;

SJF_Scheduler::SJF_Scheduler()
{
}

SJF_Scheduler::~SJF_Scheduler()
{
}

void SJF_Scheduler::sortProcesses()
{
	vector<Process>::iterator end, positionOne, positionTwo;
	bool swapped = true;

	end = processList.end();

	do
	{
		swapped = false;
		positionTwo = ++processList.begin();
		for(positionOne = processList.begin(); positionTwo != end; positionOne++, positionTwo++)
		{
			if(compareArrivalTime(positionOne, positionTwo))
			{
				swap(*positionOne, *positionTwo);
				swapped = true;
			}
		}
	}while(swapped);
}

bool SJF_Scheduler::compareArrivalTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo)
{
	return (*positionOne).getArrivalTIme() > (*positionTwo).getArrivalTIme();
}

void SJF_Scheduler::runScheduler()
{
	vector<Process>::iterator index, processListItr, end;
	vector<Process> available_queue;
	Process temp(0,0,0);
	int endTimeOfPreviousProcess = 0;



	sortProcesses();

	processListItr = processList.begin();

	do
	{
		if(processListItr != processList.end())
		{
			if(processListItr == processList.begin())
				getQueuedProcesses(available_queue, processListItr, (*processListItr).getArrivalTIme() + (*processListItr).getCPU_Burst());
			else
				getQueuedProcesses(available_queue, processListItr, endTimeOfPreviousProcess + (*index).getCPU_Burst());
		}

		index = available_queue.begin();
		end = available_queue.end();

		
		//process came in after the previous job ended
		if((*index).getArrivalTIme() > endTimeOfPreviousProcess)
		{
			(*index).setStartTime((*index).getArrivalTIme());
			(*index).setEndTime((*index).getStartTime() + (*index).getCPU_Burst());
			endTimeOfPreviousProcess = (*index).getEndTime();
			
		}
		else //process came in prior to the previous job ending
		{
			
			vector<Process>::iterator firstProcess = processList.begin();
			findProcessID(firstProcess, (*index).getProcessID());

			//very first process in the processList
			if(firstProcess == processList.begin())
			{
				(*index).setStartTime((*index).getArrivalTIme());
				(*index).setEndTime((*index).getStartTime() + (*index).getCPU_Burst());
			}
			else
			{
				(*index).setStartTime(endTimeOfPreviousProcess);
				(*index).setEndTime((*index).getStartTime() + (*index).getCPU_Burst());
				
			}
			endTimeOfPreviousProcess = (*index).getEndTime();
		}
		


		temp = (available_queue.front());
		assignValuesToProcessList(temp);
		
		available_queue.erase(index);
		index = available_queue.begin();
		end = available_queue.end();
		
		if(available_queue.size() != 0)
			sortQueueByTime(available_queue);		

	}while(available_queue.size() != 0);
	

}

void SJF_Scheduler::getQueuedProcesses(vector<Process> &available_queue, vector<Process>::iterator &processListItr, int prevProcEndTime)
{
	int endTime = prevProcEndTime;
	int arrivalTime = 0;

	vector<Process>::iterator posOne, posTwo;	
	
	endTime = prevProcEndTime;
	arrivalTime = (*processListItr).getArrivalTIme();

	while(processListItr != processList.end() && arrivalTime <= endTime)
	{		
		if(arrivalTime <= endTime && !(*processListItr).isFinished())
			available_queue.push_back(*processListItr);
	
		processListItr++;

		if(processListItr != processList.end())
			arrivalTime = (*processListItr).getArrivalTIme();
	}
}

void SJF_Scheduler::assignValuesToProcessList(Process temp)
{
	vector<Process>::iterator location;
	location = processList.begin();
	findProcessID(location, temp.getProcessID());

	(*location).setEndTime(temp.getEndTime());
	(*location).setStartTime(temp.getStartTime());
	(*location).setFinished();

}

void SJF_Scheduler::findProcessID(vector<Process>::iterator &location, int processID)
{
	while((*location).getProcessID() != processID)
		location++;
}

void SJF_Scheduler::sortQueueByTime(std::vector<Process> &queue)
{
	vector<Process>::iterator end, positionOne, positionTwo;
	bool swapped = true;

	end = queue.end();

	do
	{
		swapped = false;
		positionTwo = ++queue.begin();
		for(positionOne = queue.begin(); positionTwo != end; positionOne++, positionTwo++)
		{
			if(compareCPU_Burst(positionOne, positionTwo))
			{
				swap(*positionOne, *positionTwo);
				swapped = true;
			}
		}
	}while(swapped);
}

bool SJF_Scheduler::compareCPU_Burst(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo)
{
	return (*positionOne).getCPU_Burst() > (*positionTwo).getCPU_Burst();
}

#ifndef RR_SCHEDULER
#define RR_SCHEDULER
#include "Scheduler.h"

class RR_Scheduler : public Abstract_CPUScheduler
{
	public:
		RR_Scheduler(int quantum);
		~RR_Scheduler();
		void sortProcesses();
		void runScheduler();
		void setTimeQuantum(int quantum);



	private:
		bool compareStartTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo);
		void getQueuedProcesses(vector<Process> &available_queue, vector<Process>::iterator &processListItr, int prevProcEndTime);
		void assignValuesToProcessList(Process temp);
		void findProcessID(vector<Process>::iterator &location, int processID);
		
		

		int time_quantum;

};

#endif



#include "RR_Scheduler.h"
#include <vector>
#include <iostream>
#include <assert.h>

using namespace std;

RR_Scheduler::RR_Scheduler(int quantum)
{
	time_quantum = quantum;
}

RR_Scheduler::~RR_Scheduler()
{
}

void RR_Scheduler::setTimeQuantum(int quantum)
{
	time_quantum = quantum;
}


bool RR_Scheduler::compareStartTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo)
{
	//cout << "values: " << (*positionOne)->getStartTime() << "    " << (*positionTwo)->getStartTime();
	return (*positionOne).getArrivalTIme() > (*positionTwo).getArrivalTIme();
}

void RR_Scheduler::sortProcesses()
{
	vector<Process>::iterator end, positionOne, positionTwo;
	bool swapped = true;

	end = processList.end();

	do
	{
		swapped = false;
		positionTwo = ++processList.begin();
		for(positionOne = processList.begin(); positionTwo != end; positionOne++, positionTwo++)
		{
			if(compareStartTime(positionOne, positionTwo))
			{
				swap(*positionOne, *positionTwo);
				swapped = true;
			}
		}
	}while(swapped);
}

void RR_Scheduler::runScheduler()
{
	vector<Process>::iterator index, end, processListItr;
	vector<Process> ready_queue;
	int endTimeOfPrevProcess = 0;
	Process temp(0,0,0);

	//needed to ensure there wont be a problem with resource allocation of the vector
	//during run-time. 
	ready_queue.reserve(700);
	sortProcesses();

	processListItr = processList.begin();

	if(processListItr != processList.end())
	{
		if(processListItr == processList.begin())
			getQueuedProcesses(ready_queue, processListItr, (*processListItr).getArrivalTIme() + time_quantum);
		else
			getQueuedProcesses(ready_queue, processListItr, endTimeOfPrevProcess);
	}

	do
	{
		index = ready_queue.begin();
		end = ready_queue.end();
	
		if((*index).wasProcessed())
		{

			if((*index).getArrivalTIme() > endTimeOfPrevProcess)
			{
				if((*index).getCPU_Burst() - time_quantum <= 0)
				{
					(*index).setEndTime((*index).getStartTime() + (*index).getCPU_Burst());
					(*index).setFinished();
					assignValuesToProcessList(ready_queue.front());
				}
				else
				{
					(*index).setEndTime((*index).getArrivalTIme() + time_quantum);
					(*index).setCPU_Burst((*index).getCPU_Burst() - time_quantum);
					(*index).setProcessed();
					ready_queue.push_back(ready_queue.front());
				}

				endTimeOfPrevProcess = (*index).getEndTime();
				ready_queue.erase(index);
			}
			else
			{
				if((*index).getCPU_Burst() - time_quantum <= 0)
				{
					(*index).setEndTime(endTimeOfPrevProcess + (*index).getCPU_Burst());
					(*index).setFinished();
					assignValuesToProcessList(ready_queue.front());
				}
				else
				{
					(*index).setEndTime(endTimeOfPrevProcess + time_quantum);
					(*index).setCPU_Burst((*index).getCPU_Burst() - time_quantum);
					(*index).setProcessed();
					ready_queue.push_back(ready_queue.front());
					
				}

				endTimeOfPrevProcess = (*index).getEndTime();
				ready_queue.erase(index);
			}
		}
		else
		{
			if((*index).getArrivalTIme() > endTimeOfPrevProcess)
			{
				(*index).setStartTime((*index).getArrivalTIme());

				if((*index).getCPU_Burst() - time_quantum <= 0)
				{
					(*index).setEndTime((*index).getArrivalTIme() + (*index).getCPU_Burst());
					(*index).setFinished();
					assignValuesToProcessList(ready_queue.front());
				}
				else
				{
					(*index).setEndTime((*index).getArrivalTIme() + time_quantum);
					(*index).setCPU_Burst((*index).getCPU_Burst() - time_quantum);
					(*index).setProcessed();
					ready_queue.push_back(ready_queue.front());
				}
			}
			else
			{
				(*index).setStartTime(endTimeOfPrevProcess);
				if((*index).getCPU_Burst() - time_quantum <= 0)
				{
					(*index).setEndTime(endTimeOfPrevProcess + (*index).getCPU_Burst());
					(*index).setFinished();
					assignValuesToProcessList(ready_queue.front());
				}
				else
				{
					(*index).setEndTime(endTimeOfPrevProcess + time_quantum);
					(*index).setCPU_Burst((*index).getCPU_Burst() - time_quantum);
					(*index).setProcessed();
					ready_queue.push_back(ready_queue.front());
					
				}


			}

			
			endTimeOfPrevProcess = (*index).getEndTime();
			ready_queue.erase(index);
			
		}

		if(processListItr != processList.end())
		{
			if(processListItr == processList.begin())
				getQueuedProcesses(ready_queue, processListItr, (*processListItr).getArrivalTIme() + time_quantum);
			else
				getQueuedProcesses(ready_queue, processListItr, endTimeOfPrevProcess);
		}
	

		

		index = ready_queue.begin();
		end = ready_queue.end();

	}while(ready_queue.size() != 0);
};

void RR_Scheduler::getQueuedProcesses(vector<Process> &available_queue, vector<Process>::iterator &processListItr, int prevProcEndTime)
{
	int endTime = prevProcEndTime;
	int arrivalTime = 0;

	vector<Process>::iterator posOne, posTwo;	
	
	endTime = prevProcEndTime;
	arrivalTime = (*processListItr).getArrivalTIme();

	while(processListItr != processList.end() && arrivalTime <= endTime)
	{		
		if(arrivalTime <= endTime || available_queue.size() == 0 && (available_queue.front()).getCPU_Burst() <= time_quantum)
			available_queue.push_back(*processListItr);
	
		processListItr++;

		if(processListItr != processList.end())
			arrivalTime = (*processListItr).getArrivalTIme();
	}
}

void RR_Scheduler::assignValuesToProcessList(Process temp)
{
	vector<Process>::iterator location;
	location = processList.begin();
	findProcessID(location, temp.getProcessID());

	(*location).setEndTime(temp.getEndTime());
	(*location).setStartTime(temp.getStartTime());
	(*location).setFinished();

}

void RR_Scheduler::findProcessID(vector<Process>::iterator &location, int processID)
{
	while((*location).getProcessID() != processID)
		location++;
}


#ifndef SRTF_SCHEDULER
#define SRTF_SCHEDULER
#include "Scheduler.h"

class SRTF_Scheduler : public Abstract_CPUScheduler
{
	public:
		SRTF_Scheduler();
		void sortProcesses();
		void runScheduler();
		void printList();

	private:
		bool compareArrivalTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo);
		bool compareBurstTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo);
		bool needSwitched(vector<Process>::iterator begin, int arrival_difference);
		void sortByBurstTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo, vector<Process> &queue);
		void getQueuedProcesses(vector<Process> &available_queue, vector<Process>::iterator &processListItr, int prevProcEndTime);
		void assignValuesToProcessList(Process temp);
		void findProcessID(vector<Process>::iterator &location, int processID);

};

#endif


#include "SRTF_Scheduler.h"
#include <iostream>
#include <vector>

using namespace std;

SRTF_Scheduler::SRTF_Scheduler()
{
}

void SRTF_Scheduler::sortProcesses()
{
	vector<Process>::iterator end, positionOne, positionTwo;
	bool swapped = true;

	end = processList.end();

	do
	{
		swapped = false;
		positionTwo = ++processList.begin();
		for(positionOne = processList.begin(); positionTwo != end; positionOne++, positionTwo++)
		{
			if(compareArrivalTime(positionOne, positionTwo))
			{
				swap(*positionOne, *positionTwo);
				swapped = true;
			}
		}
	}while(swapped);
}

bool SRTF_Scheduler::compareArrivalTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo)
{
	return (*positionOne).getArrivalTIme() > (*positionTwo).getArrivalTIme();
}


bool SRTF_Scheduler::needSwitched(vector<Process>::iterator index, int arrival_difference)
{
	return (arrival_difference - (*index).getCPU_Burst() < 0) && (*(index + 1)).getCPU_Burst() < (*index).getCPU_Burst() - arrival_difference;
}


void SRTF_Scheduler::sortByBurstTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo, vector<Process> &queue)
{
	vector<Process>::iterator end, posOne, posTwo;
	bool swapped;

	posOne = positionOne;
	posTwo = (posOne + 1);

	do
	{
		cout << "ive been called ..... finally!\n";
		swapped = false;
		for(posOne = positionOne; posTwo != positionTwo; posOne++, posTwo++)
		{
			if(compareBurstTime(positionOne, positionTwo))
			{
				swap(*positionOne, *positionTwo);
				swapped = true;
			}
		}
	}while(swapped);
}

bool SRTF_Scheduler::compareBurstTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo)
{
	return (*positionOne).getCPU_Burst() > (*positionTwo).getCPU_Burst();
}

void SRTF_Scheduler::assignValuesToProcessList(Process temp)
{
	vector<Process>::iterator location;
	location = processList.begin();
	findProcessID(location, temp.getProcessID());

	(*location).setEndTime(temp.getEndTime());
	(*location).setStartTime(temp.getStartTime());
	(*location).setFinished();

}

void SRTF_Scheduler::findProcessID(vector<Process>::iterator &location, int processID)
{
	while((*location).getProcessID() != processID)
		location++;
}


void SRTF_Scheduler::runScheduler()
{
	vector<Process>::iterator index, end, tempProcessListItr, ready_queueItr;
	vector<Process> ready_queue, tempProcessList;
	int endTime = 0, arrivalTime, arrival_difference;
	Process temp(0,0,0);

	//needed to ensure there wont be a problem with resource allocation of the vector
	//during run-time. 
	ready_queue.reserve(1000);
	sortProcesses();

	tempProcessList = processList;

	ready_queue.push_back(tempProcessList.front());
	tempProcessList.erase(tempProcessList.begin());
	index = tempProcessList.begin();

	do
	{

		arrival_difference = (ready_queue.front()).getArrivalTIme() - (*index).getArrivalTIme();

		//find a candidate for switching
		while((index + 1) != tempProcessList.end() && !needSwitched(index, arrival_difference) && (*index).getArrivalTIme() < endTime)
		{
			index++;
		}

		//no candidate for switching was found, so the process will finish its run
		if((index + 1) == tempProcessList.end() || (*index).getArrivalTIme() > endTime)
		{
			(*(ready_queue.begin())).setStartTime((*(ready_queue.begin())).getArrivalTIme());
			(*(ready_queue.begin())).setEndTime((*(ready_queue.begin())).getArrivalTIme() + (*(ready_queue.begin())).getCPU_Burst());
			endTime = (*(ready_queue.begin())).getEndTime();
			assignValuesToProcessList(ready_queue.front());
			ready_queue.erase(ready_queue.begin());
		}
		else
		{ //candidate was found for context switch

			if(!(*(ready_queue.begin())).wasProcessed())
			{
				(*(ready_queue.begin())).setStartTime(endTime);
			}
			else
				(*(ready_queue.begin())).setProcessed();

			
			(*(ready_queue.begin())).setEndTime(endTime + arrival_difference);
			(*(ready_queue.begin())).setCPU_Burst((*(ready_queue.begin())).getCPU_Burst() - arrival_difference);
			endTime = (*(ready_queue.begin())).getEndTime();
			ready_queue.push_back(ready_queue.front());
			ready_queue.erase(ready_queue.begin());
			ready_queue.insert((ready_queue.begin()), *index);
		}

		ready_queue.push_back(tempProcessList.front());
		tempProcessList.erase(tempProcessList.begin());
		index = tempProcessList.begin();


	}while(ready_queue.size() != 0);

	for(vector<Process>::iterator begin = processList.begin(); begin != processList.end(); begin++)
		cout << (*begin).getArrivalTIme() << "     " << (*begin).getCPU_Burst() << endl;
}
	